package com.ruoyi.business.approvalflow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.approvalflow.domain.TRegisterApprovalFlow;
import com.ruoyi.business.approvalflow.domain.TRegisterApprovalLevelConfig;
import com.ruoyi.business.approvalflow.enums.ApprovalFlowStatus;
import com.ruoyi.business.approvalflow.mapper.TRegisterApprovalFlowMapper;
import com.ruoyi.business.approvalflow.service.ITRegisterApprovalFlowService;
import com.ruoyi.business.approvalflow.service.ITRegisterApprovalLevelConfigService;
import com.ruoyi.business.approvalflow.vo.TRegisterApprovalFlowVo;
import com.ruoyi.business.payment.utils.IdGeneratorUtils;
import com.ruoyi.business.service.ITRegisterDeptService;
import com.ruoyi.business.service.ITRegisterInfoService;
import com.ruoyi.business.service.SmsService;
import com.ruoyi.business.vo.TRegisterDeptVo;
import com.ruoyi.business.vo.TRegisterInfoVo;
import com.ruoyi.common.constant.RoleConstants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 退款审批流程Service业务层处理
 *
 * @author Tellsea
 * @date 2025-06-22
 */
@Service
public class TRegisterApprovalFlowServiceImpl extends ServiceImpl<TRegisterApprovalFlowMapper, TRegisterApprovalFlow> implements ITRegisterApprovalFlowService {

    @Autowired
    private ITRegisterApprovalLevelConfigService levelConfigService;

    @Autowired
    private ITRegisterDeptService registerDeptService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private SmsService smsService;

    @Override
    public TableDataInfo<TRegisterApprovalFlowVo> queryList(TRegisterApprovalFlowVo entity) {
        return PageUtils.buildDataInfo(this.baseMapper.queryList(PageUtils.buildPage(), entity));
    }

    @Override
    public List<TRegisterApprovalFlowVo> queryAll(TRegisterApprovalFlowVo entity) {
        return this.baseMapper.queryList(entity);
    }

    @Override
    public TRegisterApprovalFlowVo queryById(String approvalId) {
        return this.baseMapper.queryById(approvalId);
    }

    /**
     * 获取流程中待审批的数据
     *
     * @param businessIdList 业务id
     * @return res
     */
    @Override
    public List<TRegisterApprovalFlowVo> queryWaitApprove(String processId, List<String> businessIdList, Long userId) {
        return this.baseMapper.getNoApproveListByUser(processId, businessIdList, userId);
    }

    /**
     * 获取流程中待审批的数据
     *
     * @param businessIdList 业务id
     * @return res
     */
    @Override
    public List<TRegisterApprovalFlowVo> queryWaitApprove(String processId, List<String> businessIdList) {
        return this.baseMapper.getNoApproveList(processId, businessIdList);
    }

    /**
     * 创建初始化审批流程
     * @param processId 流程id
     * @param businessId 业务id
     * @param registerId 报名id
     */
    @Override
    public void initApprovalFlows(String processId, String businessId, Long registerId) {
        LambdaQueryWrapper<TRegisterApprovalFlow> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(TRegisterApprovalFlow::getProcessId,processId);
        countWrapper.eq(TRegisterApprovalFlow::getBusinessId,businessId);
        countWrapper.eq(TRegisterApprovalFlow::getRegisterId,registerId);
        int count = this.count(countWrapper);
        if(count>0){
            log.warn("当前初始化的流程已存在");
            return;
        }

        QueryWrapper<TRegisterApprovalLevelConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("process_id", processId);
        List<TRegisterApprovalLevelConfig> levels = levelConfigService.list(queryWrapper);
        if (levels.isEmpty()) {
            throw new BaseException("未配置审批流程，请联系管理员");
        }
        if (registerId == null) {
            throw new BaseException("未报名的学员");
        }
        levels.sort((o1, o2) -> o1.getLevelOrder().compareTo(o2.getLevelOrder()));
        List<TRegisterApprovalFlow> addParams = new ArrayList<>();
        for (TRegisterApprovalLevelConfig levelConfig : levels) {
            TRegisterApprovalFlow flow = new TRegisterApprovalFlow();
            flow.setProcessId(levelConfig.getProcessId());
            flow.setApprovalId(IdGeneratorUtils.generateApprovalId());
            flow.setBusinessId(businessId);
            flow.setRegisterId(registerId);
            flow.setApprovalLevel(levelConfig.getLevelOrder());
            flow.setApproverRole(levelConfig.getApproverRole());
            flow.setStatus(ApprovalFlowStatus.PENDING.getCode());
            flow.setCreateTime(DateUtils.getNowDate());
            addParams.add(flow);
        }
        TRegisterApprovalFlowServiceImpl flowService = SpringUtils.getBean(this.getClass());
        flowService.saveBatch(addParams);

        // 退款审批流程创建完后，发送短信申请
        // 要短信通知科主任，短信内容是：XX主任您好，X 科室有一位进修学员（姓名：XXX)申请了退款，请您使用电脑登录进修系统，依次点击"进修管理 / 订单管理" 查看并处理。
        // 根据进修id获取关联的科主任信息
        ITRegisterInfoService registerInfoService = SpringUtils.getBean(ITRegisterInfoService.class);
        TRegisterInfoVo tRegisterInfoVo = registerInfoService.queryById(registerId);
        // 获取关联的科室信息
        TRegisterDeptVo tRegisterDeptVo = registerDeptService.queryById(tRegisterInfoVo.getRegisterDeptId());
        // 获取科主任信息
        SysUser manageSysUser = sysUserService.selectUserById(tRegisterDeptVo.getManageUserId());
        String sendMsg = tRegisterDeptVo.getManageNickName()+"主任您好，"+
                tRegisterInfoVo.getRegisterDeptName()+" 科室有一位进修学员："+
                tRegisterInfoVo.getApplicantName()+"申请了退款，请您使用电脑登录进修系统，" +
                "依次点击 进修管理-订单管理 查看并处理。";
        if(StringUtils.isNotEmpty(manageSysUser.getPhonenumber())){
            // 发送短信
            smsService.sendMessage(manageSysUser.getPhonenumber(),sendMsg);
        }
    }

    @Transactional
    @Override
    public void processApproval(String approvalId, Integer status, String opinion) throws Exception {
        // 获取审批任务
        TRegisterApprovalFlow flow = getById(approvalId);
        if (flow == null) {
            throw new BaseException("审批任务不存在");
        }

        // 校验状态
        if (flow.getStatus() != ApprovalFlowStatus.PENDING.getCode()) {
            throw new BaseException("审批任务状态已更新");
        }
        // 检查登录人权限
        if (!hasApproveAuth(flow)) {
            throw new BaseException("当前登录人无权限审批权限");
        }
        checkApprovalProcessOrder(flow.getProcessId(), flow.getBusinessId(), flow.getApprovalLevel());
        // 更新审批状态
        flow.setApproverName(SecurityUtils.getUsername());
        flow.setApproverId(String.valueOf(SecurityUtils.getUserId()));
        flow.setStatus(status);
        flow.setApprovalOpinion(opinion);
        flow.setApprovalTime(DateUtils.getNowDate());
        updateById(flow);
    }

    /**
     * 判断是否拥有审批权限
     *
     * @param flow 流程对象
     * @return bl
     */
    private boolean hasApproveAuth(TRegisterApprovalFlow flow) {
        String approverRole = flow.getApproverRole();
        String[] roles = approverRole.split(",");
        for (String role : roles) {
            if (StringUtils.equals(role, RoleConstants.ADMIN.getRoleKey())
                    && SecurityUtils.hasRole(RoleConstants.ADMIN.getRoleKey())) {
                return true;
            }
            if (StringUtils.equals(role, RoleConstants.DEPT_MANAGE.getRoleKey())
                    && SecurityUtils.hasRole(RoleConstants.DEPT_MANAGE.getRoleKey())) {
                return true;
            }
            if (StringUtils.equals(role, RoleConstants.SECRETARY.getRoleKey())
                    && SecurityUtils.hasRole(RoleConstants.SECRETARY.getRoleKey())) {
                return true;
            }
        }

        return false;
    }

    /**
     *  检查当前审批流程顺序是否正常
     * @param businessId id
     * @param approvalLevel level
     * @throws Exception e
     */
    @Override
    public void checkApprovalProcessOrder(String processId, String businessId, Integer approvalLevel) throws Exception {
        // 如果小于当前顺序节点的数据，未审批或者已拒绝，那么当前流程不能审批
        QueryWrapper<TRegisterApprovalFlow> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("process_id", processId);
        queryWrapper.eq("business_id", businessId);
        queryWrapper.lt("approval_level", approvalLevel);
        queryWrapper.in("status", ApprovalFlowStatus.PENDING.getCode(), ApprovalFlowStatus.REJECTED.getCode());
        int flowsCnt = this.count(queryWrapper);
        if (flowsCnt > 0) {
            throw new BaseException("流程审批节点异常，请按照流程审批");
        }
    }

    /**
     * 根据流程id获取关联的所有业务流程信息
     * @param approvalId 审批id
     * @return list
     */
    @Override
    public List<TRegisterApprovalFlowVo> getAllApprovalFlowByApproval(String approvalId){
        TRegisterApprovalFlowVo approvalFlowVo = queryById(approvalId);
        // 获取所有审批任务
        TRegisterApprovalFlowVo approvalFlowVoQuery = new TRegisterApprovalFlowVo();
        approvalFlowVoQuery.setBusinessId(approvalFlowVo.getBusinessId());
        approvalFlowVoQuery.setProcessId(approvalFlowVo.getProcessId());
        List<TRegisterApprovalFlowVo> flows = queryAll(approvalFlowVoQuery);
        // 按审批级别排序
        flows.sort(Comparator.comparingInt(TRegisterApprovalFlow::getApprovalLevel));
        return flows;
    }


}
